home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- *
- * @@@BUILDINFO@@@ 61findReplaceDialog.jsx 1.0.0.47 07-Feb-2005
- * Copyright 2005 Adobe Systems Incorporated
- * All Rights Reserved.
- *
- * NOTICE: All information contained herein is, and remains the property of
- * Adobe Systems Incorporated and its suppliers, if any. The intellectual
- * and technical concepts contained herein are proprietary to Adobe Systems
- * Incorporated and its suppliers and may be covered by U.S. and Foreign
- * Patents,patents in process,and are protected by trade secret or copyright
- * law. Dissemination of this information or reproduction of this material
- * is strictly forbidden unless prior written permission is obtained from
- * Adobe Systems Incorporated.
- **************************************************************************/
-
- // The Find/Replace floating palette
-
- /* NOTES
- UIGuide exceptions:
- - no 'special character' entry: use REGEXP instead
- - Find and Replace EditText boxes should be editable DropDownLists, with max 10 entries,
- but ScriptUI does not provide such a UI element
- */
-
- // Global properties used:
- // window: LiveObject representing the main window
- // document: LiveObject representing the currently active document (script)
-
-
- /////////////////////////////////////////////////////////////////////////
- /* Create a DocFindReplace object and store it as the 'findReplaceObj'
- property of the "edit/findReplace" MenuElement and the "edit/findNext"
- MenuElement.
-
- This property is accessed by the onSelect() callback functions:
- - for the "edit/findReplace" MenuElement, to show the Find/Replace dialog.
- - for the "edit/findNext" MenuElement, to search for the current search string.
- */
-
- editMenu.findReplace.findReplaceObj = newFindAndReplaceObject (editMenu.findReplace);
- editMenu.findNext.findReplaceObj = editMenu.findReplace.findReplaceObj;
-
- /* Define the onSelect() callback function for the "edit/findReplace" MenuElement
- as a function that shows the Find and Replace dialog
- */
-
- editMenu.findReplace.onSelect = function ()
- {
- this.findReplaceObj.show();
- }
-
- /* Define the onSelect() callback function for the "edit/findNext" MenuElement
- as a function that searches for the last defined search string.
- */
-
- editMenu.findNext.onSelect = function ()
- {
- this.findReplaceObj.find(false);
- }
-
- /* The "edit/findNext" MenuElement is enabled when a current document exists
- and a search string is defined
- */
-
- editMenu.findNext.onDisplay = function()
- {
- this.enabled = (document != null) &&
- (this.findReplaceObj.currentSearchString().length > 0);
- }
-
-
- /////////////////////////////////////////////////////////////////////////
- // newFindAndReplaceObject: return a new DocFindReplace object
- function newFindAndReplaceObject (findReplMenuElement)
- {
- var findReplMenuObj = findReplMenuElement;
-
- // Localizable text strings
- const kStrFind = "$$$/ESToolkit/FindReplaceDlg/Find=&Find";
- const kStrFindNext = "$$$/ESToolkit/FindReplaceDlg/FindNext=&Find Next";
- const kStrSearchFailed = "$$$/ESToolkit/FindReplaceDlg/Alerts/SearchFailed=No matches found";
- const kStrSearchFailedRetry =
- "$$$/ESToolkit/FindReplaceDlg/Alerts/SearchFailedRetry=The end of the document has been reached.^nContinue checking from the beginning?";
- const kStrReplacementDone =
- "$$$/ESToolkit/FindReplaceDlg/Alerts/ReplacementDone=Finished replacing. %1 changes were made.";
-
- /////////////////////////////////////////////////////////////////////////
- // The Find/Replace floating palette resource
- var DFR_dlgResSpec =
- "palette { \
- properties: { closeOnKey:CLOSE_ON_KEY }, \
- text:'$$$/ESToolkit/FindReplaceDlg/title=Find and Replace', \
- orientation:'row', alignChildren:'top', \
- findPane: Group { \
- orientation:'column', alignChildren:'left', \
- search: Group { orientation:'row', \
- lbl: StaticText { \
- text:'$$$/ESToolkit/FindReplaceDlg/FindLbl=Find:', \
- }, \
- string: EditText { \
- preferredSize:[200,20], \
- helpTip:'$$$/ESToolkit/FindReplaceDlg/htFind=A text string to search for' \
- } \
- }, \
- replace: Group { orientation:'row', \
- lbl: StaticText { \
- text:'$$$/ESToolkit/FindReplaceDlg/ReplaceWith=Replace with:', \
- }, \
- string: EditText { \
- preferredSize:[200,20], \
- helpTip:'$$$/ESToolkit/FindReplaceDlg/htReplaceWith=A text string to replace the search text' \
- } \
- }, \
- opts: Group { orientation:'column', alignChildren:'left', \
- margins:[0,5,0,0], \
- matchCase: Checkbox { \
- text:'$$$/ESToolkit/FindReplaceDlg/MatchCase=Match &Case', \
- helpTip:'$$$/ESToolkit/FindReplaceDlg/htMatchCase=Only matches with the same capitalization will be found' \
- }, \
- wholeWord: Checkbox { \
- text:'$$$/ESToolkit/FindReplaceDlg/FindWholeWord=Match &Whole Word', \
- helpTip:'$$$/ESToolkit/FindReplaceDlg/htFindWholeWord=Only matches that are an entire word will be found' \
- }, \
- matchRegExp: Checkbox { \
- text:'$$$/ESToolkit/FindReplaceDlg/MatchRegExp=Match Regular E&xpression', \
- helpTip:'$$$/ESToolkit/FindReplaceDlg/htMatchRegExp=Only strings which match the given regular expression will be found' \
- }, \
- } \
- }, \
- btnsPane: Group { \
- orientation:'column', alignChildren:'fill', \
- find: Button { \
- helpTip:'$$$/ESToolkit/FindReplaceDlg/Btn/htFind=Find the specified text string' \
- }, \
- replace: Button { \
- text:'$$$/ESToolkit/FindReplaceDlg/Btn/Replace=&Replace', \
- helpTip:'$$$/ESToolkit/FindReplaceDlg/Btn/htReplace=Replace the selected text with the specified text' \
- }, \
- replaceFind: Button { \
- text:'$$$/ESToolkit/FindReplaceDlg/Btn/ReplaceFind=Replace && Fi&nd', \
- helpTip:'$$$/ESToolkit/FindReplaceDlg/Btn/htReplaceFind=Replace the selected text with the specified text, and find the next occurence' \
- }, \
- replaceAll: Button { \
- text:'$$$/ESToolkit/FindReplaceDlg/Btn/ReplaceAll=Replace &All',\
- helpTip:'$$$/ESToolkit/FindReplaceDlg/Btn/htReplaceAll=Replace all occurences of the selected text with the specified text' \
- }, \
- done: Button { \
- text:'$$$/ESToolkit/FindReplaceDlg/Btn/Done=&Done', \
- helpTip:'$$$/ESToolkit/FindReplaceDlg/Btn/htDone=Close the Find and Replace dialog' \
- } \
- } \
- }";
-
- /////////////////////////////////////////////////////////////////////////
- // Define a DocFindReplace object
- function DocFindReplace (findReplMenuItem) { this.initSelf(findReplMenuItem); }
-
- /////////////////////////////////////////////////////////////////////////
- // Define the DocFindReplace 'public method' functions
-
- /* find(searchWholeDoc)
- Search for the search text.
- * If 'searchWholeDoc' is true, search the entire document,
- otherwise search from the insertion point to the end of the document.
-
- Returns true if the search was successful, false if not.
-
- Called from the Find button event handler, or
- from a keyboard shortcut handler.
- */
- function DFR_find (searchWholeDoc)
- {
- var options = this.getMatchOptions (searchWholeDoc);
- with (this.palette.findPane) {
- var searchString = search.string.text;
- // Remember that we searched for this text, for preferences
- search.activeSearchString = searchString;
- if (document.find (searchString, options)) {
- // Match found: reset search state
- this.resetFindReplace (false);
- return true;
- }
- else {
- /* Match not found: if already in 'search the whole doc'
- mode, note the search failure, else, ask if user
- wants to search from the beginning */
- if (searchWholeDoc) {
- // Already searched whole doc: we're done
- app.beep();
- messageBox (this.strSearchFailed);
- this.resetFindReplace (true);
- return false;
- }
- else if (queryBox (this.strSearchFailedRetry)) {
- // Search again, from the top, but don't allow a global search again
- this.resetFindReplace (false);
- return this.find (true);
- }
- else {
- this.resetFindReplace (true);
- return false;
- }
- }
- }
- } // DFR_find
-
- /* replace(replaceAll, searchWholeDoc)
- Replace the currently selected text with the contents of
- findPane.replace.string.text.
- * If 'replaceAll' is true, replace all instances of the selected
- text in the document.
- * If 'searchWholeDoc' is true, search the entire document,
- otherwise search from the insertion point to the end of the document.
- Return:
- * true if a match was found
-
- Called from the Replace, Replace & Find, and Replace All button
- event handlers, or from a keyboard shortcut handler.
- */
- function DFR_replace (replaceAll, searchWholeDoc)
- {
- var options = this.getMatchOptions (searchWholeDoc);
- if (replaceAll)
- options += Document.FIND_REPLACEALL;
- with (this.palette.findPane) {
- var searchString = search.string.text;
- var replaceString = replace.string.text;
- // Remember that we searched for this text, for preferences
- search.activeSearchString = searchString;
- // Remember that we used this text for replacements, for preferences
- replace.activeReplaceString = replaceString;
- var replacements = document.replace (searchString, replaceString, options);
- if (replacements > 0) {
- // Match(es) found: reset search state
- this.resetFindReplace (false);
- if (replaceAll)
- // Tell user how many replacements were made
- messageBox (this.strReplacementDone, replacements);
- return true;
- }
- else {
- /* Match not found: if already in 'search the whole doc'
- mode, note the search failure, else, ask if user
- wants to search from the beginning */
- if (searchWholeDoc) {
- // Already searched whole doc: we're done
- messageBox (this.strSearchFailed);
- this.resetFindReplace (true);
- return false;
- }
- else if (queryBox (this.strSearchFailedRetry)) {
- // Search again, from the top, but don't allow a global search again
- this.resetFindReplace (false);
- return this.replace (replaceAll, true);
- }
- else {
- this.resetFindReplace (true);
- return false;
- }
- }
- }
- } // DFR_replace
-
- /* show()
- show the Find/Replace palette. If this is the first call to show()
- in this invocation of the IDE, load (or create) the find/replace preferences.
- Called from the Find/Replace menu item onSelect handler
- */
- function DFR_show ()
- {
- if (this.initialShow) {
- /* First time to show the palette:
- Look for the prefs object for the DocFindReplace object.
- If not defined yet, create one with default values.
- Initialize the UI controls with the preference settings.
- */
- this.initialShow = false;
- if (typeof prefs.findReplacePrefs == "undefined") {
- // Create initial prefs object and define default property values
- prefs.findReplacePrefs = {};
- for (var i = 0; i < this.prefsProperties.length; i++)
- prefs.findReplacePrefs[this.prefsProperties[i][0]] = this.prefsProperties[i][1];
- }
- prefs.findReplacePrefs.toSource = DFR_prefsToSource;
- this.initFromPrefs (prefs.findReplacePrefs);
- }
-
- // On each 'show', reset the find & replace strings and the states of the buttons
- with (this.palette.findPane) {
- /* Replace current 'Find' string if a selection is active in current document.
- For multi-line selections, use only the first line */
- var selection = document.selectedText;
- var nlIndex = selection.indexOf ('\n');
- if (nlIndex >= 0)
- selection = selection.substring (0, nlIndex);
- if (selection.length == 0)
- // Use last known search string
- search.string.text = search.activeSearchString;
- else
- // Use the selection (up to first newline)
- search.string.text = selection;
- replace.string.text = replace.activeReplaceString;
- }
- this.resetFindReplace (true);
-
- this.palette.show();
-
- // After the window is visible, give the 'search' edit field the focus
- this.resetFocus (this.palette.findPane.search.string);
- } // DFR_show
-
-
- /////////////////////////////////////////////////////////////////////////
- // Define the DocFindReplace 'private method' functions
-
- // initSelf(): called from the DocFindReplace ctor
- function DFR_initSelf (findReplMenuElement)
- {
- // Remember our menu item object
- this.menuItem = findReplMenuElement;
-
- // Create the floating palette, link it to the FindReplace object
- var resourceSpec;
- /* define platform-specific hotkeys to close the palette:
- Alt+F4 on Windows and Cmd+W on the Mac */
- if (File.fs == "Windows")
- resourceSpec = this.dlgResSpec.replace ("CLOSE_ON_KEY", '"Alt+F4"');
- else
- resourceSpec = this.dlgResSpec.replace ("CLOSE_ON_KEY", '"Cmd+W"');
- this.palette = new Window (resourceSpec);
- this.palette.findReplaceObj = this;
-
- // Set update event handlers for Find and Replace strings
- with (this.palette.findPane) {
- search.string.onChanging = function ()
- {
- // Search string is changing: make 'Find' button respond to
- // Enter key and reset FindReplace controls state
- var palette = this.parent.parent.parent;
- palette.defaultElement = palette.btnsPane.find;
- palette.findReplaceObj.resetFindReplace (true);
- }
- replace.string.onChanging = function ()
- {
- // Replace string is changing: make 'Replace' button respond to
- // Enter key and reset FindReplace controls state
- var palette = this.parent.parent.parent;
- palette.defaultElement = palette.btnsPane.replace;
- palette.findReplaceObj.resetFindReplace (true);
- }
- }
-
- // Set update event handlers for 'match options' checkboxes
- with (this.palette.findPane) {
- opts.matchCase.onClick =
- opts.wholeWord.onClick =
- opts.matchRegExp.onClick = function ()
- {
- // A match option is changing: reset FindReplace controls state
- var palette = this.parent.parent.parent;
- palette.findReplaceObj.resetFindReplace (true);
- }
- }
-
- // Set onClick event handlers for the buttons pane
- with (this.palette.btnsPane) {
- find.onClick = function ()
- {
- var frObj = this.parent.parent.findReplaceObj;
- frObj.find (false);
- /* We want the search string to retain the focus after a
- Find/Find Next, so it is easy to change the string.
- Because Find/Find Next is the default button, it will
- get Enter keystrokes even if the search string has the
- focus, unlike in the Replace and Replace & Find cases below. */
- frObj.resetFocus (frObj.palette.findPane.search.string);
- };
- replace.onClick = function ()
- {
- var frObj = this.parent.parent.findReplaceObj;
- var replaced = frObj.replace (false, false);
- /* After a successful Replace, we want the focus to
- stay on the Replace button, so the user can easily do
- another Replace by typing Enter. If the Replace was
- unsuccessful, return the focus to the search string, so
- it can be easily changed. */
- if (replaced)
- frObj.resetFocus (frObj.palette.btnsPane.replace);
- else
- frObj.resetFocus (frObj.palette.findPane.search.string);
- };
- replaceFind.onClick = function ()
- {
- var frObj = this.parent.parent.findReplaceObj;
- var replacedAndFound = false;
- if (frObj.replace (false, false))
- // Only do the 'follow on' find if the replace() matched
- replacedAndFound = frObj.find (false);
- /* After a successful Replace & Find, we want the focus to
- stay on the 'Replace & Find' button, so the user can easily do
- another 'Replace & Find' by typing Enter. If the Replace was
- unsuccessful, return the focus to the search string, so
- it can be easily changed. */
- if (replacedAndFound)
- frObj.resetFocus (frObj.palette.btnsPane.replaceFind);
- else
- frObj.resetFocus (frObj.palette.findPane.search.string);
- };
- replaceAll.onClick = function ()
- {
- var frObj = this.parent.parent.findReplaceObj;
- frObj.replace (true, false);
- /* After a 'Replace All', always return the focus to the
- search string, so it can be easily changed. */
- frObj.resetFocus (frObj.palette.findPane.search.string);
- };
- done.onClick = function ()
- {
- this.parent.parent.close();
- };
- }
-
- // Make the 'Done' button respond to the Esc key
- this.palette.cancelElement = this.palette.btnsPane.done;
-
- // Define an onShow event handler that will execute each time the dialog is shown
- this.palette.onShow = function ()
- {
- // Adjust widths of some text labels for alignment
- with (this.findPane) {
- var maxWidth = replace.lbl.size.width;
- var findWidth = search.lbl.size.width;
- if (findWidth > maxWidth)
- maxWidth = findWidth;
- search.lbl.size.width = maxWidth;
- replace.lbl.size.width = maxWidth;
- this.layout.layout(true);
- }
- };
- } // DFR_initSelf
-
-
- /* initFromPrefs()
- Initialize values of various controls from the saved 'preference' values.
- Called from first 'show' of the F/R palette.
- */
- function DFR_initFromPrefs (frPrefs)
- {
- with (this.palette) {
- if (frPrefs.paletteLocation != null)
- frameLocation = frPrefs.paletteLocation;
- else
- this.palette.center(window);
- }
- with (this.palette.findPane) {
- search.activeSearchString = frPrefs.searchString;
- replace.activeReplaceString = frPrefs.replaceString;
- opts.matchCase.value = frPrefs.matchCase;
- opts.wholeWord.value = frPrefs.wholeWord;
- opts.matchRegExp.value = frPrefs.matchRegExp;
- if (search.activeSearchString.length > 0)
- // Initially, if there's a search string, make the
- // Find button respond to Enter key
- this.palette.defaultElement = this.palette.btnsPane.find;
- }
- this.resetFindReplace (true);
- } // DFR_initFromPrefs
-
-
- /* updatePrefs()
- Update the find/replace 'preferences' object with current values from the controls.
- */
- function DFR_updatePrefs (frPrefs)
- {
- with (this.palette) {
- frPrefs.paletteLocation = frameLocation;
- }
- with (this.palette.findPane) {
- frPrefs.searchString = search.activeSearchString;
- frPrefs.replaceString = replace.activeReplaceString;
- frPrefs.matchCase = opts.matchCase.value;
- frPrefs.wholeWord = opts.wholeWord.value;
- frPrefs.matchRegExp = opts.matchRegExp.value;
- }
- } // DFR_updatePrefs
-
-
- /* resetFindReplace()
- Reset states of the 'find' and 'replace' controls after a state change.
- 'newSearch' indicates a new search string: false means searching again
- for same string.
- */
- function DFR_resetFindReplace (newSearch)
- {
- var palette = this.palette;
- var haveSearchString = this.currentSearchString().length > 0;
- var docIsWriteable = true; // replace with "! document.readOnly" if we need to disable F/R for RO docs
- with (palette.btnsPane) {
- find.text = localize (newSearch ? this.strFind : this.strFindNext);
- find.enabled = haveSearchString;
- replace.enabled = (haveSearchString && docIsWriteable);
- replaceFind.enabled = (haveSearchString && docIsWriteable);
- replaceAll.enabled = (haveSearchString && docIsWriteable);
- }
- } // DFR_resetFindReplace
-
-
- /* resetFocus(control)
- Set keyboard focus to the given 'control', or to the palette if control == null.
- */
- function DFR_resetFocus (control)
- {
- var palette = this.palette;
- palette.active = true;
- if (control)
- control.active = true;
- } // DFR_resetFocus
-
-
- /* getMatchOptions()
- Return the 'match options' flags to pass to Document.find() or
- Document.replace(), based on the current dialog match options
- checkboxes and the 'searchWholeDoc' parameter.
- */
- function DFR_getMatchOptions (searchWholeDoc)
- {
- var options = 0;
- with (this.palette.findPane) {
- if (searchWholeDoc)
- options += Document.FIND_WRAPAROUND;
- if (opts.matchCase.value == 0)
- options += Document.FIND_IGNORECASE;
- if (opts.wholeWord.value != 0)
- options += Document.FIND_WORDS;
- if (opts.matchRegExp.value != 0)
- options += Document.FIND_REGEXP;
- }
- return options;
- } // DFR_getMatchOptions
-
- /* currentSearchString()
- Return the current string to search for: may be empty.
- */
- function DFR_currentSearchString ()
- {
- return this.palette.findPane.search.string.text;
- } // currentSearchString
-
- /* DFR_prefsToSource()
- Return a string that is executable code which creates the findReplacePrefs object.
- DFR_prefsToSource is assigned as the toSource() function for the findReplacePrefs object.
- */
- function DFR_prefsToSource()
- {
- // Get the DocFindReplace object: it has the names of preference properties
- var frObj = editMenu.findReplace.findReplaceObj;
-
- // Update the find/replace preference object with current preferences values.
- frObj.updatePrefs (prefs.findReplacePrefs);
-
- /* Iterate thru the find/replace preference properties, appending each
- property name / value pair to the source string we are building */
- var src = "{ ";
- for (var i = 0; i < frObj.prefsProperties.length; i++) {
- if (i > 0)
- src += ", ";
- src += strVal (prefs.findReplacePrefs, frObj.prefsProperties[i][0]);
- }
- src += " }";
- return src;
-
- // Utility that returns a string for the named 'prop' / value pair
- function strVal (prefs, prop)
- {
- var str = prop + ": ";
- var value = prefs[prop];
- if (typeof value == 'object')
- str += value.toSource();
- else if (typeof value == "string")
- str += "'" + value.toString() + "'";
- else
- str += value.toString();
- return str;
- }
- } // DFR_prefsToSource
-
-
- /////////////////////////////////////////////////////////////////////////
- // Attach 'public methods' to Object's prototype
- DocFindReplace.prototype.find = DFR_find;
- DocFindReplace.prototype.replace = DFR_replace;
- DocFindReplace.prototype.show = DFR_show;
-
- // Attach 'private methods' to Object's prototype
- DocFindReplace.prototype.initSelf = DFR_initSelf;
- DocFindReplace.prototype.initFromPrefs = DFR_initFromPrefs;
- DocFindReplace.prototype.updatePrefs = DFR_updatePrefs;
- DocFindReplace.prototype.resetFindReplace = DFR_resetFindReplace;
- DocFindReplace.prototype.resetFocus = DFR_resetFocus;
- DocFindReplace.prototype.getMatchOptions = DFR_getMatchOptions;
- DocFindReplace.prototype.currentSearchString = DFR_currentSearchString;
-
- // Attach 'member variables' to Object's prototype
- DocFindReplace.prototype.strFind = kStrFind;
- DocFindReplace.prototype.strFindNext = kStrFindNext;
- DocFindReplace.prototype.strSearchFailed = kStrSearchFailed;
- DocFindReplace.prototype.strSearchFailedRetry = kStrSearchFailedRetry;
- DocFindReplace.prototype.strReplacementDone = kStrReplacementDone;
- DocFindReplace.prototype.dlgResSpec = DFR_dlgResSpec;
-
- /////////////////////////////////////////////////////////////////////////
- // Create an instance, set some initial values, and return it
- var frObj = new DocFindReplace(findReplMenuElement);
- frObj.initialShow = true;
- frObj.prefsProperties = [
- ["paletteLocation", null],
- ["matchCase", false],
- ["wholeWord", false],
- ["matchRegExp", false],
- ["searchString", ""],
- ["replaceString", ""]
- ];
-
- return frObj;
-
- } // newFindAndReplaceObject
-
-
-